﻿namespace Pap.Web.Modules.Membership.Views
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.UI.WebControls;
    using Coolite.Ext.Web;
    using global::Utils.UIPermission;
    using Pap.Data;
    using Pap.Web.Modules.Membership.ViewModel;
    using Pap.Web.Utils;

    /// <summary>
    /// the code-behin class for UserDetails page
    /// </summary>
    public partial class UserDetails : BasePage<UserDetailsViewModel>, IPermittedPage
    {
        #region [ Variables ]

        /// <summary>
        /// 
        /// </summary>
        private IUser _User;
        /// <summary>
        /// 
        /// </summary>
        private List<Guid> _Roles;
        /// <summary>
        /// 
        /// </summary>
        private List<Guid> _committees;

        /// <summary>
        /// 
        /// </summary>
        private List<Guid> _projects;

        #endregion

        #region [ Query strings ]

        /// <summary>
        /// Gets the editing user ID.
        /// </summary>
        private string EditingUserID
        {
            get
            {
                return Request.QueryString["UserID"];
            }
        }

        #endregion

        #region [ Fill Controls ]

        /// <summary>
        /// Fills the controls.
        /// </summary>
        /// <param name="user">The user.</param>
        private void FillControls(IUser user)
        {
            if (!string.IsNullOrEmpty(EditingUserID))
            {
                txtUserName.Text = user.Username;
                txtPass.Visible = false;
                txtConfirmPassword.Visible = false;
                txtPass.Text = user.Password;
                txtConfirmPassword.Text = user.Password;
                dtpBirthDate.Value = user.Birthdate;
                txtDisplayName.Text = user.DisplayName;
                txtEmail.Text = user.Email;
                txtJobTitle.Text = user.JobTitle;
            }
        }

        /// <summary>
        /// Fills the roles.
        /// </summary>
        private void FillRoles()
        {
            lstRole.DataSource = this.ViewModel.GetAllRoles();
            lstRole.DataBind();
        }

        /// <summary>
        /// Fills the committees.
        /// </summary>
        private void FillCommittees()
        {
            lstcommittees.DataSource = this.ViewModel.GetAllCommittees();
            lstcommittees.DataBind();
        }


       /// <summary>
        /// Fills the projects.
        /// </summary>
        private void FillProjects()
        {
            lstProjects.DataSource = this.ViewModel.GetAllProjects();
            lstProjects.DataBind();
        }

        #endregion

        #region [ Events ]

        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            if (this.ViewModel != null)
            {
                if (!Ext.IsAjaxRequest)
                {
                    if (!Page.IsPostBack)
                    {
                        FillProjects();
                        if (!string.IsNullOrEmpty(EditingUserID))
                        {
                            this._User = this.ViewModel.GetUserByID(EditingUserID.ToGuid());
                            //---------------------------------------------------------------
                            MainForm.Title = string.Format("{0} ({1})", GetLocalResourceObject("TitleEditUser").ToString(), _User.Username);
                            FillControls(_User);
                            this.lstRole.ItemDataBound += new DataListItemEventHandler(this.lstRole_ItemDataBound);
                            this.lstcommittees.ItemDataBound += new DataListItemEventHandler(this.lstcommittees_ItemDataBound);
                            this.lstProjects.ItemDataBound += new DataListItemEventHandler(this.lstProjects_ItemDataBound);
                        }

                        dtpBirthDate.MaxDate = DateTime.Today.AddYears(-15);
                        FillRoles();
                        FillCommittees();
                        FillProjects();

                    }
                }
            }
        }

        /// <summary>
        /// Handles the ItemDataBound event of the lstRole control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.DataListItemEventArgs"/> instance containing the event data.</param>
        protected void lstRole_ItemDataBound(object sender, DataListItemEventArgs e)
        {
            if (e.Item.DataItem != null)
            {
                var role = e.Item.DataItem as IRole;
                if (role != null)
                {
                    var checkBox = e.Item.FindControl("chkSelect") as Checkbox;
                    //---------------------------------------------------------
                    checkBox.Checked = this._User.Roles.Any(r => r.RoleID == role.RoleID);
                }
            }
        }

        /// <summary>
        /// Handles the ItemDataBound event of the lstcommittees control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.DataListItemEventArgs"/> instance containing the event data.</param>
        protected void lstcommittees_ItemDataBound(object sender, DataListItemEventArgs e)
        {
            if (e.Item.DataItem != null)
            {
                var committee = e.Item.DataItem as ICommittee;
                if (committee != null)
                {
                    var checkBox = e.Item.FindControl("chkSelect") as Checkbox;
                    //---------------------------------------------------------
                    checkBox.Checked = this._User.UsersCommittees.Any(c => c.CommitteeID == committee.CommitteeID);
                }
            }
        }

        /// <summary>
        /// Handles the ItemDataBound event of the lstcommittees control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.DataListItemEventArgs"/> instance containing the event data.</param>
        protected void lstProjects_ItemDataBound(object sender, DataListItemEventArgs e)
        {
            if (e.Item.DataItem != null)
            {
                var project = e.Item.DataItem as IProject;
                if (project != null)
                {
                    var checkBox = e.Item.FindControl("chkSelect") as Checkbox;
                    //---------------------------------------------------------
                    checkBox.Checked = this._User.UserProjects.Any(c => c.ProjectID == project.ProjectID);
                }
            }
        }

        /// <summary>
        /// Handles the Clicked event of the btnSubmit control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void btnSubmit_Clicked(object sender, AjaxEventArgs e)
        {
            Page.Validate();
            if (this.IsValid)
            {
                try
                {
                    FormStatusBar.ShowBusy(GetLocalResourceObject("MSGWorking").ToString());
                    if (!string.IsNullOrEmpty(EditingUserID))
                    {
                        Guid userId = EditingUserID.ToGuid();
                        this.ViewModel.UpdateUser(userId, txtUserName.Text, txtPass.Text, txtDisplayName.Text, (DateTime)dtpBirthDate.Value, txtEmail.Text, txtJobTitle.Text, _Roles, _committees, _projects);
                        //--------------------------------------------------------------
                        Ext.Redirect("~/Membership.route/UsersList", GetLocalResourceObject("MSGRedirecting").ToString());
                    }
                    else
                    {
                        this.ViewModel.CreateUser(txtUserName.Text, txtPass.Text, txtDisplayName.Text, (DateTime)dtpBirthDate.Value, txtEmail.Text, txtJobTitle.Text, _Roles, _committees, _projects);
                        //--------------------------------------------------------------
                        ClearControls();
                    }

                    FormStatusBar.SetStatus(new StatusBarStatusConfig { Text = GetLocalResourceObject("MBDoneText").ToString(), IconCls = "", Clear2 = true });
                }
                catch
                {
                    FormStatusBar.SetStatus(new StatusBarStatusConfig { Text = GetLocalResourceObject("MBCantSave").ToString(), IconCls = "", Clear2 = true });
                }
            }
            else
            {
                FormStatusBar.SetStatus(new StatusBarStatusConfig { Text = GetLocalResourceObject("MBFormInvalid").ToString(), IconCls = "", Clear2 = true });
            }
        }

        /// <summary>
        /// Handles the Clicked event of the btnCancel control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void btnCancel_Clicked(object sender, AjaxEventArgs e)
        {
            Ext.Redirect("~/Membership.route/UsersList", GetLocalResourceObject("MSGRedirecting").ToString());
        }

        /// <summary>
        /// Handles the Validate event of the txtUserName control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.ServerValidateEventArgs"/> instance containing the event data.</param>
        protected void txtUserName_Validate(object sender, ServerValidateEventArgs e)
        {
            if (!ValidateName())
            {
                e.IsValid = false;
            }
        }

        /// <summary>
        /// Handles the Validate event of the txtEmail control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.ServerValidateEventArgs"/> instance containing the event data.</param>
        protected void txtEmail_Validate(object sender, ServerValidateEventArgs e)
        {
            if (!ValidateEmail())
            {
                e.IsValid = false;
            }
        }

        /// <summary>
        /// Handles the Validate event of the lstRole control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.ServerValidateEventArgs"/> instance containing the event data.</param>
        protected void lstRole_Validate(object sender, ServerValidateEventArgs e)
        {
            _Roles = GetCheckedRoles();
            if (_Roles.Count == 0)
            {
                txtUserName.MarkInvalid(GetLocalResourceObject("MBNoRolesSelected").ToString());
                //Ext.Msg.Configure(new MessageBox.Config
                //{
                //    Title =
                //    GetLocalResourceObject("MBErrorCaption").ToString(),
                //    Message = GetLocalResourceObject("MBNoRolesSelected").ToString(),
                //    Buttons = MessageBox.Button.OK,
                //    Icon = MessageBox.Icon.ERROR
                //}).Show();
                e.IsValid = false;
            }
        }

        /// <summary>
        /// Handles the Validate event of the lstCommittee control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.ServerValidateEventArgs"/> instance containing the event data.</param>
        protected void lstCommittee_Validate(object sender, ServerValidateEventArgs e)
        {
            _committees = GetCheckedCommittees();
            if (_committees.Count == 0)
            {
                txtUserName.MarkInvalid(GetLocalResourceObject("MBNoCommitteeSelected").ToString());
                //Ext.Msg.Configure(new MessageBox.Config
                //{
                //    Title = GetLocalResourceObject("MBErrorCaption").ToString(),
                //    Message = GetLocalResourceObject("MBNoCommitteeSelected").ToString(),
                //    Buttons = MessageBox.Button.OK,
                //    Icon = MessageBox.Icon.ERROR
                //}).Show();
                e.IsValid = false;
            }
        }

        /// <summary>
        /// Handles the Validate event of the lstProject control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.ServerValidateEventArgs"/> instance containing the event data.</param>
        protected void lstProject_Validate(object sender, ServerValidateEventArgs e)
        {
            _projects = GetCheckedProjects();
            if (_projects.Count == 0)
            {
                txtUserName.MarkInvalid(GetLocalResourceObject("MBNoProjectsSelected").ToString());
                e.IsValid = false;
            }
        }

        #endregion

        #region [ Functions ]

        /// <summary>
        /// Validates the name.
        /// </summary>
        /// <returns></returns>
        [AjaxMethod]
        public bool ValidateName()
        {
            if (!string.IsNullOrEmpty(txtUserName.Text))
            {
                bool valid = true;
                if (string.IsNullOrEmpty(EditingUserID))
                {
                    if (this.ViewModel.DoesUserNameExist(txtUserName.Text, null))
                    {
                        valid = false;
                        txtUserName.MarkInvalid(GetLocalResourceObject("MsgUserNameIsUsed").ToString());
                    }
                }
                else
                {
                    if (this.ViewModel.DoesUserNameExist(txtUserName.Text, EditingUserID.ToGuid()))
                    {
                        valid = false;
                        txtUserName.MarkInvalid(GetLocalResourceObject("MsgUserNameIsUsed").ToString());
                    }
                }
                return valid;
            }
            return true;
        }

        /// <summary>
        /// Validates the email.
        /// </summary>
        /// <returns></returns>
        [AjaxMethod]
        public bool ValidateEmail()
        {
            if (!string.IsNullOrEmpty(txtEmail.Text))
            {
                bool valid = true;
                if (string.IsNullOrEmpty(EditingUserID))
                {
                    if (this.ViewModel.DoesUserEmailExist(txtEmail.Text, null))
                    {
                        valid = false;
                        txtEmail.MarkInvalid(GetLocalResourceObject("MsgEmailIsUsed").ToString());
                    }
                }
                else
                {
                    if (this.ViewModel.DoesUserEmailExist(txtEmail.Text, EditingUserID.ToGuid()))
                    {
                        valid = false;
                        txtEmail.MarkInvalid(GetLocalResourceObject("MsgEmailIsUsed").ToString());
                    }
                }
                return valid;
            }
            return true;
        }

        /// <summary>
        /// Gets the checked roles.
        /// </summary>
        /// <returns>
        /// List of guids of the checked roles IDs
        /// </returns>
        private List<Guid> GetCheckedRoles()
        {
            List<Guid> roles = new List<Guid>();
            foreach (DataListItem item in lstRole.Items)
            {
                Checkbox checkBox = item.FindControl("chkSelect") as Checkbox;
                if (checkBox.Checked)
                {
                    HiddenField hidden = item.FindControl("txtID") as HiddenField;
                    roles.Add(hidden.Value.ToGuid());
                }
            }
            return roles;
        }

        /// <summary>
        /// Gets the checked committees.
        /// </summary>
        /// <returns></returns>
        private List<Guid> GetCheckedCommittees()
        {
            List<Guid> committees = new List<Guid>();
            foreach (DataListItem item in lstcommittees.Items)
            {
                Checkbox checkBox = item.FindControl("chkSelect") as Checkbox;
                if (checkBox.Checked)
                {
                    HiddenField hidden = item.FindControl("txtID") as HiddenField;
                    committees.Add(hidden.Value.ToGuid());
                }
            }
            return committees;
        }

        /// <summary>
        /// Gets the checked Projects.
        /// </summary>
        /// <returns></returns>
        private List<Guid> GetCheckedProjects()
        {
            List<Guid> Projects = new List<Guid>();
            foreach (DataListItem item in lstProjects.Items)
            {
                Checkbox checkBox = item.FindControl("chkSelect") as Checkbox;
                if (checkBox.Checked)
                {
                    HiddenField hidden = item.FindControl("txtID") as HiddenField;
                    Projects.Add(hidden.Value.ToGuid());
                }
            }
            return Projects;
        }

        /// <summary>
        /// Clears the controls.
        /// </summary>
        private void ClearControls()
        {
            txtUserName.Reset();
            txtPass.Reset();
            txtConfirmPassword.Reset();
            txtDisplayName.Reset();
            txtEmail.Reset();
            dtpBirthDate.Reset();
            txtJobTitle.Reset();

            foreach (DataListItem item in lstRole.Items)
            {
                var checkBox = item.FindControl("chkSelect") as Checkbox;
                checkBox.Checked = false;
            }

            foreach (DataListItem item in lstcommittees.Items)
            {
                var checkBox = item.FindControl("chkSelect") as Checkbox;
                checkBox.Checked = false;
            }

            foreach (DataListItem item in lstProjects.Items)
            {
                var checkBox = item.FindControl("chkSelect") as Checkbox;
                checkBox.Checked = false;
            }

        }

        #endregion

        #region IPermittedPage Members

        /// <summary>
        /// Gets the name of the permission.
        /// </summary>
        /// <value>
        /// The name of the permission.
        /// </value>
        public string PermissionName
        {
            get { return "UserDetails"; }
        }

        #endregion
    }
}
